package com.itxiuyixiu.volunteer.controller;

import com.itxiuyixiu.entity.enums.ActivityState;
import com.itxiuyixiu.entity.model.*;
import com.itxiuyixiu.tools.util.returns.ReturnVo;
import com.itxiuyixiu.volunteer.common.errors.ServiceException;
import com.itxiuyixiu.volunteer.dto.*;
import com.itxiuyixiu.volunteer.service.OrganizationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Optional;

/**
 * @author 黄磊
 * @date 2020/5/3
 */
@Api(tags = "志愿者组织API")
@RequestMapping("/organization")
@RestController
public class OrganizationController {
    private final OrganizationService organizationService;

    public OrganizationController(OrganizationService organizationService) {
        this.organizationService = organizationService;
    }

    /**
     * 返回志愿者组织信息
     *
     * @return 返回信息
     */
    @ApiOperation(value = "返回志愿者组织信息", response = Organization.class)
    @GetMapping("/message")
    public ReturnVo findOrganizationMessage() {
        Organization organization = organizationService.findOrganizationMessage();
        if (organization == null) {
            return ReturnVo.getFailureReturn("获取志愿者信息失败");
        }
        return ReturnVo.getSuccessReturn(organization);
    }

    /**
     * 修改用户志愿者组织信息
     *
     * @param dto 志愿者组织信息
     * @return 返回信息
     */
    @ApiOperation(value = "修改用户志愿者组织信息", response = String.class)
    @PutMapping("/message")
    public ReturnVo modifyOrganizationMessage(@Valid OrganizationModifyMessageParam dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnVo.getFailureReturn(bindingResult);
        }
        organizationService.modifyOrganizationMessage(dto);
        return ReturnVo.getSuccessReturn("成功修改志愿者组织信息");
    }

    /**
     * 创建志愿者项目
     *
     * @param project 志愿者项目信息
     * @return 返回信息
     */
    @ApiOperation(value = "创建志愿者项目", response = String.class)
    @PostMapping("/project")
    public ReturnVo saveProject(@Valid ProjectSaveParam project, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnVo.getFailureReturn(bindingResult);
        }
        return ReturnVo.getSuccessReturn(organizationService.saveProject(project));
    }

    /**
     * 查询用户的所有志愿者项目
     *
     * @return 返回信息
     */
    @ApiOperation(value = "查询用户的所有志愿者项目", response = Project.class, responseContainer = "List")
    @GetMapping("/projects")
    public ReturnVo findAllProject() {
        return ReturnVo.getSuccessReturn(organizationService.findAllProject());
    }

    /**
     * 查询特定的志愿者项目
     *
     * @param projectId 志愿者项目id
     * @return 返回信息
     */
    @ApiOperation(value = "查询特定的志愿者项目", response = Project.class)
    @GetMapping("/project/{projectId}")
    public ReturnVo findProjectById(@PathVariable("projectId") Integer projectId) {
        Project project = organizationService.findProjectByProjectId(projectId);
        if (project == null) {
            return ReturnVo.getFailureReturn("没有找到相应的志愿者项目");
        }
        return ReturnVo.getSuccessReturn(project);
    }

    /**
     * 修改志愿者项目信息
     *
     * @param projectId 项目id
     * @param dto       项目信息
     * @return 返回信息
     */
    @ApiOperation(value = "修改志愿者项目信息", response = String.class)
    @PutMapping("/project/{projectId}")
    public ReturnVo modifyProject(@PathVariable("projectId") Integer projectId, @Valid ProjectModifyMessageParam dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnVo.getFailureReturn(bindingResult);
        }
        switch (organizationService.modifyProject(projectId, dto)) {
            case 0:
                return ReturnVo.getSuccessReturn("成功修改志愿者项目信息");
            case 1:
                return ReturnVo.getFailureReturn("志愿者项目未找到");
            case 2:
                return ReturnVo.getFailureReturn("要修改的志愿者项目不属于您");
            default:
                return ReturnVo.getFailureReturn("服务器发生未知错误");
        }
    }

    /**
     * 删除志愿者项目
     *
     * @param projectId 志愿者项目id
     * @return 返回信息
     */
    @ApiOperation(value = "删除志愿者项目", response = String.class)
    @DeleteMapping("/project/{projectId}")
    public ReturnVo deleteProject(@PathVariable("projectId") Integer projectId) {
        switch (organizationService.deleteProject(projectId)) {
            case 0:
                return ReturnVo.getSuccessReturn("成功删除志愿者项目");
            case 1:
                return ReturnVo.getFailureReturn("志愿者项目未找到");
            case 2:
                return ReturnVo.getFailureReturn("要修改的志愿者项目不属于您");
            default:
                return ReturnVo.getFailureReturn("服务器发生未知错误");
        }
    }

    /**
     * 添加志愿者活动
     *
     * @param activity 项目活动
     * @return 活动id
     */
    @ApiOperation(value = "添加志愿者活动", response = Integer.class)
    @PostMapping("/activity/activity")
    public ReturnVo saveActivity(@Validated ActivitySaveParam activity, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnVo.getFailureReturn(bindingResult);
        }
        int flag;
        try {
            flag = organizationService.saveActivity(activity);
        } catch (ServiceException e) {
            return ReturnVo.getFailureReturn(e.getMessage());
        }
        return ReturnVo.getSuccessReturn("活动申请成功", flag);
    }

    /**
     * 获取用户的所有志愿者活动
     *
     * @return 志愿者活动
     */
    @ApiOperation(value = "获取用户的所有志愿者活动", response = Activity.class, responseContainer = "List")
    @GetMapping("/activity/activities")
    public ReturnVo getAllActivity() {
        return ReturnVo.getSuccessReturn(organizationService.findAllActivity());
    }

    /**
     * 获取特定的志愿者活动信息
     *
     * @param activityId 志愿者活动信息
     * @return 志愿者活动信息
     */
    @ApiOperation(value = "获取自己的所有志愿者项目", response = Activity.class)
    @GetMapping("/activity/activity/{activityId}")
    public ReturnVo getActivityById(@PathVariable("activityId") Integer activityId) {
        Activity activity = organizationService.findActivityByActivityId(activityId);
        if (activity == null) {
            return ReturnVo.getFailureReturn("未找到相应的志愿者活动信息");
        }
        return ReturnVo.getSuccessReturn(activity);
    }

    /**
     * 修改志愿者活动信息
     *
     * @param activityId 要修改的志愿者活动id
     * @param activity   修改后的志愿者活动信息
     * @return 修改状态
     */
    @ApiOperation(value = "修改志愿者活动信息", response = String.class)
    @PutMapping("/activity/activity/{activityId}")
    public ReturnVo modifyActivityById(@PathVariable("activityId") Integer activityId, @Valid ActivityModifyMessageParam activity, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnVo.getFailureReturn(bindingResult);
        }
        try {
            organizationService.modifyActivity(activityId, activity);
        } catch (ServiceException e) {
            return ReturnVo.getFailureReturn(e.getMessage());
        }
        return ReturnVo.getSuccessReturn("修改志愿者活动信息成功");
    }

    /**
     * 根据志愿者项目id查询志愿者活动
     *
     * @param projectId 项目id
     * @return 志愿者活动信息
     */
    @ApiOperation(value = "根据志愿者项目id查询志愿者活动", response = Activity.class, responseContainer = "List")
    @GetMapping("/activity/project/{projectId}")
    public ReturnVo findAllActivityByProjectId(@PathVariable("projectId") Integer projectId) {
        return ReturnVo.getSuccessReturn(organizationService.findAllActivityByProjectId(projectId));
    }

    /**
     * 修改志愿者活动的状态（取消）
     *
     * @param activityId    要修改activityId活动的状态
     * @param activityState 把活动修改到activityState状态
     * @return 修改情况
     */
    @ApiOperation(value = "修改志愿者活动的状态（取消）", response = String.class)
    @PutMapping("/activity/status/{activityId}")
    public ReturnVo modifyActivityState(@PathVariable("activityId") Integer activityId, @NotNull(message = "活动状态不能为空") ActivityState activityState) {
        try {
            organizationService.modifyActivityState(activityId, activityState);
            return ReturnVo.getSuccessReturn("修改活动状态成功");
        } catch (ServiceException e) {
            return ReturnVo.getFailureReturn(e.getMessage());
        }
    }

    /**
     * 查询所有学生信息
     *
     * @return 学生信息
     */
    @ApiOperation(value = "查询所有学生信息", response = Student.class, responseContainer = "List")
    @GetMapping("/student/students")
    public ReturnVo findAllStudent() {
        try {
            return ReturnVo.getSuccessReturn(organizationService.findAllStudent());
        } catch (ServiceException e) {
            return ReturnVo.getFailureReturn(e.getMessage());
        }
    }

    /**
     * 查询特定学生信息
     *
     * @param sId 要查询的学生id
     * @return 学生信息
     */
    @ApiOperation(value = "查询特定学生信息", response = Student.class)
    @GetMapping("/student/student/{sId}")
    public ReturnVo findStudentBySId(@PathVariable("sId") Integer sId) {
        try {
            Optional<Student> studentOptional = organizationService.findStudentBySId(sId);
            return studentOptional.map(ReturnVo::getSuccessReturn).orElseGet(() -> ReturnVo.getFailureReturn("学生信息没有查询到"));
        } catch (ServiceException e) {
            return ReturnVo.getFailureReturn(e.getMessage());
        }
    }

    /**
     * 上传学生信息
     *
     * @param student 学生信息
     * @return 上传情况
     */
    @ApiOperation(value = "上传学生信息", response = String.class)
    @PostMapping("/student/student")
    public ReturnVo saveStudent(@Valid StudentSaveParam student, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnVo.getFailureReturn(bindingResult);
        }
        try {
            organizationService.saveStudent(student);
            return ReturnVo.getSuccessReturn("成功添加学生信息");
        } catch (ServiceException e) {
            return ReturnVo.getFailureReturn(e.getMessage());
        }
    }

    /**
     * 修改学生信息
     *
     * @param sId     要修改的信息的学生表主键
     * @param student 修改后的学生信息
     * @return 修改情况
     */
    @ApiOperation(value = "修改学生信息", response = String.class)
    @PutMapping("/student/student/{sId}")
    public ReturnVo modifyStudent(@PathVariable("sId") Integer sId, @Valid StudentModifyMessageParam student, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnVo.getFailureReturn(bindingResult);
        }
        try {
            organizationService.modifyStudent(sId, student);
            return ReturnVo.getSuccessReturn("成功修改学生信息");
        } catch (ServiceException e) {
            return ReturnVo.getFailureReturn(e.getMessage());
        }
    }

    @ApiOperation(value = "获取所有未认证学生信息", response = TempStudent.class, responseContainer = "List")
    @GetMapping("/student/temps")
    public ReturnVo findAllTempStudent() {
        try {
            return ReturnVo.getSuccessReturn(organizationService.findAllTempStudent());
        } catch (ServiceException e) {
            return ReturnVo.getFailureReturn(e.getMessage());
        }
    }

    @ApiOperation(value = "审核学生", response = Object.class)
    @PutMapping("/student/temp/{tempStudentId}")
    public ReturnVo findAllTempStudent(@PathVariable("tempStudentId") Integer tempStudentId, @RequestParam boolean pass) {
        try {
            organizationService.passTempStudent(tempStudentId, pass);
            if (pass) {
                return ReturnVo.getSuccessReturn("成功通过学生认证");
            } else {
                return ReturnVo.getSuccessReturn("成功未通过学生认证");
            }
        } catch (ServiceException e) {
            return ReturnVo.getFailureReturn(e.getMessage());
        }
    }

    @GetMapping("/activity/enters/{activityId}")
    public ReturnVo findAllEnterListByActivityId(@PathVariable("activityId") Integer activityId) {
        return ReturnVo.getSuccessReturn(organizationService.findAllEnterListByActivityId(activityId));
    }

    @GetMapping("/activity/enter/{enterId}")
    public ReturnVo findEnterListById(@PathVariable("enterId") Integer enterId) {
        Optional<EnterListView> enterListOptional = organizationService.findEnterListById(enterId);
        return enterListOptional.map(ReturnVo::getSuccessReturn).orElseGet(() -> ReturnVo.getFailureReturn("要查询的活动记录不存在"));
    }

    @PutMapping("/activity/enter/{enterId}")
    public ReturnVo modifyEnterListById(@PathVariable("enterId") Integer enterId, @Valid EnterListModifyMessageParam enterList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ReturnVo.getFailureReturn(bindingResult);
        }
        switch (organizationService.modifyEnterList(enterId, enterList)) {
            case 0:
                return ReturnVo.getSuccessReturn("成功修改活动参与记录");
            case 1:
                return ReturnVo.getFailureReturn("要修改的记录不存在");
            case 2:
                return ReturnVo.getFailureReturn("要修改的活动参与记录不属于您");
            default:
                return ReturnVo.getFailureReturn("服务器发生未知错误");
        }
    }

    @DeleteMapping("/activity/enter/{enterId}")
    public ReturnVo deleteEnterList(@PathVariable("enterId") Integer enterId) {
        switch (organizationService.deleteEnterList(enterId)) {
            case 0:
                return ReturnVo.getSuccessReturn("成功删除活动参与者");
            case 1:
                return ReturnVo.getFailureReturn("要删除的信息不存在");
            case 2:
                return ReturnVo.getFailureReturn("要删除的信息不属于您");
            default:
                return ReturnVo.getSuccessReturn("服务器发生未知错误");
        }
    }
}
